package com.example.foobar.business.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.example.foobar.business.service.*;
import com.example.foobar.dao.service.DaUserChangeRecordDaoService;
import com.example.foobar.dto.DABaseDTO;
import com.example.foobar.entity.*;
import com.example.foobar.param.DaUserChangeRecordPageParam;
import io.geekidea.springbootplus.framework.core.pagination.Paging;
import io.geekidea.springbootplus.framework.util.DateUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 分析系统配置文件 服务实现类
 *
 * @author 郑英奔
 * @since 2021-05-31
 */
@Slf4j
@Service
public class DaUserChangeRecordServiceImpl implements DaUserChangeRecordService {

    @Autowired
    private DaUserChangeRecordDaoService daUserChangeRecordDaoService;

    @Autowired
    private ImsPzGuanhuaiTrackService imsPzGuanhuaiTrackService;

    @Autowired
    private ImsGhostCustomActiveRecordService imsGhostCustomActiveRecordService;

    @Autowired
    private DaNewCommerCountService daNewCommerCountService;

    @Autowired
    private DaQrcodeNewCommerCountService daQrcodeNewCommerCountService;

    @Autowired
    private  ImsGhostQrcodeRecordsService imsGhostQrcodeRecordsService;

    @Autowired
    private DaQrcodeRecordsService daQrcodeRecordsService;

    @Override
    public boolean saveDaUserChangeRecord(DaUserChangeRecord daUserChangeRecord) {
        return daUserChangeRecordDaoService.saveDaUserChangeRecord(daUserChangeRecord);
    }

    @Override
    public boolean updateDaUserChangeRecord(DaUserChangeRecord daUserChangeRecord) {
        return daUserChangeRecordDaoService.updateDaUserChangeRecord(daUserChangeRecord);
    }

    @Override
    public boolean deleteDaUserChangeRecord(Long id) {
        return daUserChangeRecordDaoService.deleteDaUserChangeRecord(id);
    }

    @Override
    public DaUserChangeRecord getById(Long id) {
        return daUserChangeRecordDaoService.getById(id);
    }

    @Override
    public Paging<DaUserChangeRecord> getDaUserChangeRecordPageList(DaUserChangeRecordPageParam daUserChangeRecordPageParam) {
        return daUserChangeRecordDaoService.getDaUserChangeRecordPageList(daUserChangeRecordPageParam);
    }

    @Override
    //保存昨天的新增用户，取消关注用户，活跃用户（text用户，event用户），其中活跃用户在采集完成后会删除。
    public void recordUserChange(Date date) {

        List<DaUserChangeRecord> daUserChangeRecords = getAndSaveDaUserChangeRecords(date);

        daUserChangeRecordDaoService.remove(new QueryWrapper<DaUserChangeRecord>().eq("date", date));

        Map<String, List<DaUserChangeRecord>> listGroupByUniacid = daUserChangeRecords.stream().collect(Collectors.groupingBy(item -> {
            return item.getUniacid().toString();
        }));


        Map<String, List<DaUserChangeRecord>> listGroupByUniacidAndType = daUserChangeRecords.stream().collect(Collectors.groupingBy(item -> {
            return item.getUniacid() + "_" + item.getType();
        }));

        List<DaNewCommerCount> daNewCommerCountList = new ArrayList<>();

        listGroupByUniacid.keySet().stream().forEach(key ->{
            int subscribeCount = CollectionUtil.isNotEmpty(listGroupByUniacidAndType.get(key + "_" + "subscribe")) ? listGroupByUniacidAndType.get(key + "_" + "subscribe").size() : 0;
//            int unsubscribeCount = CollectionUtil.isNotEmpty(listGroupByUniacidAndType.get(key + "_" + "unsubscribe")) ? listGroupByUniacidAndType.get(key + "_" + "unsubscribe").size() : 0;
            DaNewCommerCount daNewCommerCount = new DaNewCommerCount();
            daNewCommerCount.setUniacid(Integer.valueOf(key));
            daNewCommerCount.setDate(date);
//            daNewCommerCount.setAmount(subscribeCount - unsubscribeCount);
            daNewCommerCount.setAmount(subscribeCount);
            daNewCommerCountList.add(daNewCommerCount);
        });
        daNewCommerCountService.saveBatch(daNewCommerCountList);


        pullQrcodeNewCommerCount(date);
    }

    private void pullQrcodeNewCommerCount(Date date) {
        List<DaQrcodeRecords> daQrcodeRecords = getAndSaveDaQrcodeRecords(date);

        pullQrcodeNewCommerCountData(date, daQrcodeRecords);
    }

    private void pullQrcodeNewCommerCountData(Date date, List<DaQrcodeRecords> daQrcodeRecords) {
        Map<String, List<DaQrcodeRecords>> qrcodeRecordGroupBySceneId = daQrcodeRecords.stream().collect(Collectors.groupingBy(item -> {
            return item.getSceneId().toString();
        }));


        List<DaQrcodeNewCommerCount> daQrcodeNewCommerCountList = new ArrayList<>();
        qrcodeRecordGroupBySceneId.keySet().stream().forEach(sceneId ->{
            DaQrcodeNewCommerCount daQrcodeNewCommerCount = new DaQrcodeNewCommerCount();
            daQrcodeNewCommerCount.setAmount(qrcodeRecordGroupBySceneId.get(sceneId).size());
            daQrcodeNewCommerCount.setDate(date);
            daQrcodeNewCommerCount.setSceneId(sceneId);
            daQrcodeNewCommerCountList.add(daQrcodeNewCommerCount);
        });
        daQrcodeNewCommerCountService.remove(new QueryWrapper<DaQrcodeNewCommerCount>().eq("date", date));
        daQrcodeNewCommerCountService.saveBatch(daQrcodeNewCommerCountList);
    }

    private List<DaQrcodeRecords> getAndSaveDaQrcodeRecords(Date date) {
        QueryWrapper<ImsGhostQrcodeRecords> wrapper = new QueryWrapper<>();
        wrapper.gt("create_time", new Date(DateUtil.getDayStartTime(date).getTime()));
        wrapper.lt("create_time", new Date(DateUtil.getDayEndTime(date).getTime()));
        wrapper.eq("event", DaNewCommerCountServiceImpl.MESSAGE_TYPE_SUBSCRIBE);
        List<ImsGhostQrcodeRecords> imsPzGuanhuaiTracks = imsGhostQrcodeRecordsService.list(wrapper);
        List<DaQrcodeRecords> collect = imsPzGuanhuaiTracks.stream().map(this::convertToDaQrcpdeRecprds).collect(Collectors.toList());


        QueryWrapper<DaQrcodeRecords> daQrcodeRecordsQueryWrapper = new QueryWrapper<>();
        daQrcodeRecordsQueryWrapper.gt("create_time", new Date(DateUtil.getDayStartTime(date).getTime()));
        daQrcodeRecordsQueryWrapper.lt("create_time", new Date(DateUtil.getDayEndTime(date).getTime()));
        daQrcodeRecordsQueryWrapper.eq("event", DaNewCommerCountServiceImpl.MESSAGE_TYPE_SUBSCRIBE);
        daQrcodeRecordsService.remove(daQrcodeRecordsQueryWrapper);
        daQrcodeRecordsService.saveBatch(collect);
        return collect;
    }

    private DaQrcodeRecords convertToDaQrcpdeRecprds(ImsGhostQrcodeRecords imsGhostQrcodeRecords) {
        DaQrcodeRecords daQrcodeRecords = new DaQrcodeRecords();
        BeanUtils.copyProperties(imsGhostQrcodeRecords, daQrcodeRecords);
        return daQrcodeRecords;
    }

    @Override
    public void recordUserChangeFromYingMa(Date date) {

        //保存用户活跃记录（新增，活跃），保存新增用户统计数据
        pullNewComerCount(date);


        //保存扫描关注用户记录，保存扫码新增用户统计数据
//        pullQrcodeNewCommerCount(date);
    }

    private void pullNewComerCount(Date date) {
        List<DaUserChangeRecord> collect = getAndSaveDaUserChangeRecords(date);

        pullNewCommerCountData(date, collect);
    }

    private void pullNewCommerCountData(Date date, List<DaUserChangeRecord> collect) {
        Map<String, List<DaUserChangeRecord>> listGroupByUniacid = collect.stream().collect(Collectors.groupingBy(item -> {
            return item.getUniacid().toString();
        }));

        Map<String, List<DaUserChangeRecord>> listGroupByUniacidAndType = collect.stream().collect(Collectors.groupingBy(item -> {
            return item.getUniacid() + "_" + item.getType();
        }));

        List<DaNewCommerCount> daNewCommerCountList = new ArrayList<>();

        listGroupByUniacid.keySet().stream().forEach(key ->{
            int subscribeCount = CollectionUtil.isNotEmpty(listGroupByUniacidAndType.get(key + "_" + DaNewCommerCountServiceImpl.MESSAGE_TYPE_SUBSCRIBE))
                    ? listGroupByUniacidAndType.get(key + "_" + DaNewCommerCountServiceImpl.MESSAGE_TYPE_SUBSCRIBE).size() : 0;
            DaNewCommerCount daNewCommerCount = new DaNewCommerCount();
            daNewCommerCount.setUniacid(Integer.valueOf(key));
            daNewCommerCount.setDate(date);
            daNewCommerCount.setAmount(subscribeCount);
            daNewCommerCountList.add(daNewCommerCount);
        });
        daNewCommerCountService.remove(new QueryWrapper<DaNewCommerCount>().eq("date", date));
        daNewCommerCountService.saveBatch(daNewCommerCountList);
    }

    private List<DaUserChangeRecord> getAndSaveDaUserChangeRecords(Date date) {
        List<DaUserChangeRecord> collect = getDaUserChangeRecordsFromYingMa(date);

//        以下两行需放开
        daUserChangeRecordDaoService.remove(new QueryWrapper<DaUserChangeRecord>().eq("date", date));
        daUserChangeRecordDaoService.saveBatch(collect);
        return collect;
    }

    private List<DaUserChangeRecord> getDaUserChangeRecordsFromYingMa(Date date) {
        List<ImsGhostCustomActiveRecord> imsPzGuanhuaiTracks = imsGhostCustomActiveRecordService.listByDate(date);

        List<DaUserChangeRecord> collect = imsPzGuanhuaiTracks.stream().map(this::imsGhostCustomActiveRecordConvertToDaUserChangeRecord).collect(Collectors.toList());
        return collect;
    }

    private DaUserChangeRecord imsGhostCustomActiveRecordConvertToDaUserChangeRecord(ImsGhostCustomActiveRecord imsGhostCustomActiveRecord){
        DaUserChangeRecord daUserChangeRecord = new DaUserChangeRecord();
        daUserChangeRecord.setDate(imsGhostCustomActiveRecord.getDate());
        daUserChangeRecord.setOpenid(String.valueOf(imsGhostCustomActiveRecord.getOpenid()));
        daUserChangeRecord.setType(imsGhostCustomActiveRecord.getAction());
        daUserChangeRecord.setUniacid(imsGhostCustomActiveRecord.getUniacid());

        return daUserChangeRecord;
    }

    @Override
    public List<DABaseDTO> getUserActiveRate(String uniacid, Date baseDate, Date date) {
        Map<String, Object> params = new HashMap<>();
        params.put("baseDate", baseDate);
        params.put("date", date);
        params.put("uniacid", uniacid);
        return daUserChangeRecordDaoService.getUserActiveRate(params);
    }

    @Override
    public List<DABaseDTO> getUserActiveRateforYingMa(String uniacid, Date baseDate, Date date) {
        Map<String, Object> params = new HashMap<>();
        params.put("baseDate", baseDate);
        params.put("date", date);
        params.put("uniacid", uniacid);
        return daUserChangeRecordDaoService.getUserActiveRateForYingMa(params);
    }

    @Override
    public void deleteYesterdayActiveRecord(Date date) {
        daUserChangeRecordDaoService.remove(new QueryWrapper<DaUserChangeRecord>().eq("date", date)
                .ne("type", DaNewCommerCountServiceImpl.MESSAGE_TYPE_SUBSCRIBE));
    }

    @Override
    public List<DaUserChangeRecord> list(Wrapper<DaUserChangeRecord> wrapper){
        return daUserChangeRecordDaoService.list(wrapper);
    }

    @Override
    public int count(Wrapper<DaUserChangeRecord> wrapper) {
        return daUserChangeRecordDaoService.count(wrapper);
    }

    @Override
    public List<DABaseDTO> getQrcodeUserActiveRateforYingMa(String sceneId, Date baseDate, Date date) {
        Map<String, Object> params = new HashMap<>();

        params.put("baseDateStart", new Date(DateUtil.getDayStartTime(baseDate).getTime()));
        params.put("baseDateEnd", new Date(DateUtil.getDayEndTime(baseDate).getTime()));
        params.put("date", date);
        params.put("sceneId", sceneId);
        return daUserChangeRecordDaoService.getQrcodeUserActiveRateforYingMa(params);
    }

    private DaUserChangeRecord convertToUserChange(ImsPzGuanhuaiTrack imsPzGuanhuaiTrack) {
        DaUserChangeRecord daUserChangeRecord = new DaUserChangeRecord();
        daUserChangeRecord.setDate(imsPzGuanhuaiTrack.getDate());
        daUserChangeRecord.setOpenid(String.valueOf(imsPzGuanhuaiTrack.getOpenid()));
        daUserChangeRecord.setType(imsPzGuanhuaiTrack.getMessageType());
        daUserChangeRecord.setUniacid(imsPzGuanhuaiTrack.getUniacid());

        return daUserChangeRecord;
    }
}
